package com.iquizoo.webflux.mvcstyle.controller;

import com.iquizoo.webflux.mvcstyle.domain.User;
import com.iquizoo.webflux.mvcstyle.repository.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @author: wangkui
 * @date: 2018/11/1 21:34
 * @desc:
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    private final UserRepository userRepository;

    public UserController(UserRepository userRepository)
    {
        this.userRepository = userRepository;
    }

    /**
     * 数组形式一次性返回
     * @return
     */
    @GetMapping("/")
    public Flux<User> getAll()
    {
        log.info("/");
        return userRepository.findAll();
    }

    /**
     * SSE方式多次返回数据
     * @return
     */
    @GetMapping(path = "/stream/all", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<User> streamGetAll()
    {
        log.info("/stream/all");
        return userRepository.findAll();
    }

    @PostMapping("/")
    public Mono<User> createUser(@RequestBody User user)
    {
        log.info("create user={}", user);
        return userRepository.save(user);
    }

    /**
     * 存在返回200，不存在返回404
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    public Mono<ResponseEntity<Void>> deleteUser(@PathVariable String id)
    {
        // 当操作数据并返回Mono，这个时候使用flatMap
        // 不操作数据，只是转换，使用map
        return userRepository.findById(id).flatMap(user -> userRepository.delete(user).then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK)))).defaultIfEmpty(new ResponseEntity<Void>(HttpStatus.NOT_FOUND));
    }

    @PutMapping("/{id}")
    public Mono<ResponseEntity<User>> editUser(@PathVariable String id, @RequestBody User user)
    {
        return userRepository.findById(id).flatMap(u -> {
            BeanUtils.copyProperties(user, u);
            u.setId(id);
            return userRepository.save(u);
        }).map(u -> new ResponseEntity<User>(u, HttpStatus.OK)).defaultIfEmpty(new ResponseEntity<User>(HttpStatus.NOT_FOUND));
    }

    @GetMapping("/{id}")
    public Mono<ResponseEntity<User>> findById(@PathVariable String id)
    {
        return userRepository.findById(id).map(user -> new ResponseEntity<User>(user, HttpStatus.OK)).defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }


}
